package fr.utbm.gi.in56.message;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import fr.utbm.gi.in56.ads.AdType;
import fr.utbm.gi.in56.ads.AdsManager;
import fr.utbm.gi.in56.database.DatabaseServlet;
import fr.utbm.gi.in56.error.ErrorType;
import fr.utbm.gi.in56.notification.NotificationType;
import fr.utbm.gi.in56.user.UserBean;
import fr.utbm.gi.in56.user.UserManager;

/**
 * Servlet implementation class SendMessageServlet
 * 
 * @author Adrien Hoffer & Tarik Belabbas
 */
@WebServlet("/SendMessageServlet")
public class SendMessageServlet extends DatabaseServlet
{
	/**
	 * Version number associated to the serializable class. 
	 */
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public SendMessageServlet()
    {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		request.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
		
		// Get the recipient
		String recipient = request.getParameter( "recipient" ); //$NON-NLS-1$
		UserManager userMg = new UserManager( getConnection() );
		if ( userMg.isValidUser( recipient ) )
		{
			forwardToErrorPage( request, response, ErrorType.MESSAGE_INVALID_RECIPIENT );
			return;
		}
			
		// Get the current user
		HttpSession session = request.getSession( true );
		UserBean user = (UserBean)session.getAttribute( "currentSessionUser" ); //$NON-NLS-1$
		if ( user.getLogin().compareTo( recipient ) == 0 )
		{
			forwardToErrorPage( request, response, ErrorType.MESSAGE_CANNOT_SEND_TO_YOURSELF_SERIOUSLY );
			return;
		}
		
		// Get the ad id
		String adIdString = request.getParameter( "adId" ); //$NON-NLS-1$
		int adId = 0;
		try
		{
			adId = Integer.parseInt( adIdString );
		}
		catch (NumberFormatException e)
		{
			forwardToErrorPage( request, response, ErrorType.MESSAGE_INVALID_AD );
			return;
		}
		
		// Get the ad type
		String adType = request.getParameter( "adType" ); //$NON-NLS-1$
		AdType adTypeEnum = AdType.NONE;
		try
		{
			adTypeEnum = AdType.valueOf( adType.toUpperCase() ); 
		}
		catch ( Exception _exception ) // IllegalArgumentException or NullPointerException
		{
			forwardToErrorPage( request, response, ErrorType.MESSAGE_INVALID_AD_TYPE );
			return;
		}
		
		// Get the message type
		String msgType = request.getParameter( "msgType" ); //$NON-NLS-1$
		MessageType msgTypeEnum = MessageType.NONE;
		try
		{
			msgTypeEnum = MessageType.valueOf( msgType.toUpperCase() ); 
		}
		catch ( Exception _exception ) // IllegalArgumentException or NullPointerException
		{
			forwardToErrorPage( request, response, ErrorType.MESSAGE_INVALID_MSG_TYPE );
			return;
		}
		
		// Check that this type of message can be sent to the recipient about the ad
		MessageManager messageMg = new MessageManager( getConnection() );
		ErrorType result = messageMg.canSendMessageTo( user.getLogin(), recipient, adId, adTypeEnum, msgTypeEnum );
		if ( result != ErrorType.NONE )
		{
			forwardToErrorPage( request, response, result );
			return;
		}
		
		// Get the ad title
		AdsManager adsMg = new AdsManager( getConnection() );
		String adTitle = adsMg.getAdTitle( adId, AdType.valueOf( adType.toUpperCase() ) );
		
		request.setAttribute( "recipient", recipient ); //$NON-NLS-1$
		request.setAttribute( "adId", adId ); //$NON-NLS-1$
		request.setAttribute( "adType", adType ); //$NON-NLS-1$
		request.setAttribute( "adTitle", adTitle ); //$NON-NLS-1$
		request.setAttribute( "msgType", msgType ); //$NON-NLS-1$
		
		RequestDispatcher rd = request.getRequestDispatcher( "sendMessage.jsp" ); //$NON-NLS-1$
		rd.forward( request, response );
	}
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost( HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException
	{
		request.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
		
		// Get the recipient
		String recipient = request.getParameter( "recipient" ); //$NON-NLS-1$
		UserManager userMg = new UserManager( getConnection() );
		if ( userMg.isValidUser( recipient ) )
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_RECIPIENT );
			return;
		}
			
		// Get the current user
		HttpSession session = request.getSession( true );
		UserBean user = (UserBean)session.getAttribute( "currentSessionUser" ); //$NON-NLS-1$
		if ( user.getLogin().compareTo( recipient ) == 0 )
		{
			returnError( request, response, ErrorType.MESSAGE_CANNOT_SEND_TO_YOURSELF_SERIOUSLY );
			return;
		}
		
		// Get the ad id
		String adIdString = request.getParameter( "adId" ); //$NON-NLS-1$
		int adId = 0;
		try
		{
			adId = Integer.parseInt( adIdString );
		}
		catch (NumberFormatException e)
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_AD );
			return;
		}
		
		// Get the ad type
		String adType = request.getParameter( "adType" ); //$NON-NLS-1$
		AdType adTypeEnum = AdType.NONE;
		try
		{
			adTypeEnum = AdType.valueOf( adType.toUpperCase() ); 
		}
		catch ( Exception _exception ) // IllegalArgumentException or NullPointerException
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_AD_TYPE );
			return;
		}
		
		// Get the message type
		String msgType = request.getParameter( "msgType" ); //$NON-NLS-1$
		MessageType msgTypeEnum = MessageType.NONE;
		try
		{
			msgTypeEnum = MessageType.valueOf( msgType.toUpperCase() ); 
		}
		catch ( Exception _exception ) // IllegalArgumentException or NullPointerException
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_MSG_TYPE );
			return;
		}
		
		// Check that this type of message can be sent to the recipient about the ad
		MessageManager messageMg = new MessageManager( getConnection() );
		ErrorType result = messageMg.canSendMessageTo( user.getLogin(), recipient, adId, adTypeEnum, msgTypeEnum );
		if ( result != ErrorType.NONE )
		{
			returnError( request, response, result );
			return;
		}
		
		// Get message subject
		String subject = request.getParameter( "subject" ); //$NON-NLS-1$
		if ( ( subject == null ) || ( subject.isEmpty() ) )
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_SUBJECT );
			return;
		}
		
		// Get message
		String message = request.getParameter( "message" ); //$NON-NLS-1$
		if ( ( message == null ) || ( message.isEmpty() ) )
		{
			returnError( request, response, ErrorType.MESSAGE_INVALID_MESSAGE );
			return;
		}
		
		MessageManager msgMg = new MessageManager( getConnection() );
		result = msgMg.sendMessage( recipient, user.getLogin(), adId, subject, message, adTypeEnum );
		if ( result != ErrorType.NONE )
		{
			returnError( request, response, result );
			return;
		}
		
		request.setAttribute( "notification", NotificationType.MESSAGE_SENT ); //$NON-NLS-1$
		RequestDispatcher rd = request.getRequestDispatcher("notification.jsp"); //$NON-NLS-1$
		rd.forward( request, response );
		return;
	}
	
	/**
	 * Sets the error as request attribute and forward to error page.
	 * 
	 * @param _error the error
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void forwardToErrorPage( HttpServletRequest request,
			HttpServletResponse response, ErrorType _error ) throws ServletException, IOException
	{
		request.setAttribute( "error", _error ); //$NON-NLS-1$
		RequestDispatcher rd = request.getRequestDispatcher("error.jsp"); //$NON-NLS-1$
		rd.forward( request, response );
	}
	
	/**
	 * Sets the error as request attribute, set message parameters as attributes
	 * and forward to previous page.
	 * 
	 * @param _error the error
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void returnError( HttpServletRequest request,
			HttpServletResponse response, ErrorType _error ) throws ServletException, IOException
	{
		request.setAttribute( "recipient", request.getParameter( "recipient" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "adId", Integer.parseInt( request.getParameter( "adId" ) ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "adType", request.getParameter( "adType" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "adTitle", request.getParameter( "adTitle" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "msgType", request.getParameter( "msgType" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "subject", request.getParameter( "subject" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		request.setAttribute( "message", request.getParameter( "message" ) ); //$NON-NLS-1$ //$NON-NLS-2$
		
		request.setAttribute( "sendMessageError", _error ); //$NON-NLS-1$
		RequestDispatcher rd = request.getRequestDispatcher("sendMessage.jsp"); //$NON-NLS-1$
		rd.forward( request, response );
	}
}
